home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
9-Digit Zip Code Directory
/
9-Digit Zip Code Directory (American Business Information) (ABIZIP-12).ISO
/
z4src.zip
/
Z4RANGE.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1995-09-14
|
11KB
|
360 lines
//----------------------------------------------------------------------------
// MODULE DESCRIPTION
//
// Module: z4numcp.cpp
// Title: ZIP+4 Engine
// Notice: John M. Weeder
// Copyright (c) 1993. All rights reserved.
// This module contains proprietary information and should be
// treated as confidential.
//
//----------------------------------------------------------------------------
// MAINTENANCE HISTORY
//
// $Workfile$
// $Revision$
// $Author$
// $Date$
// $Log$
//
//----------------------------------------------------------------------------
// MODULE NARRATIVE
//
// This module contains code for the class Z4_RANGE.
//
// The code in this module may be written in C++ or C.
//
// This module is portable to:
// DOS 3.X+
// MS Windows 3.X+
// OS/2 2.X+
// OS/2 2.0 PM
//
// The following compilers are supported:
// MSC 6.0A
// MSC/C++ 7.0
// Borland C++ 3.1 for DOS
// Borland C++ 1.0 for OS/2 2.X
//
//----------------------------------------------------------------------------
#include <z4.h>
//----------------------------------------------------------------------------
// Description: Default constructor
// Parameters:
// Returns:
//----------------------------------------------------------------------------
FN_M Z4_RANGE::Z4_RANGE()
{
Z4_RANGE::Initialize(CL_INIT_CLASS);
}
//----------------------------------------------------------------------------
// Description: Destructor
// Parameters:
// Returns:
//----------------------------------------------------------------------------
FN_M Z4_RANGE::~Z4_RANGE()
{
Z4_RANGE::Destroy(FALSE);
}
//----------------------------------------------------------------------------
// Description:
// Parameters:
// Returns: TRUE if successful.
//----------------------------------------------------------------------------
BOOL FN_M Z4_RANGE::Break(PCSZ pcsz, RZ4_NO range)
{
memset(&range, 0, sizeof(range));
range.code = Z4_BOTH;
while (pcsz[0])
if (isalpha(pcsz[0])) // Alpha
{
range.szNo[range.cNo][0] = pcsz[0];
// already has zero...range.szNo[range.cNo][1] = '\0';
range.afAlpha[range.cNo] = TRUE;
range.cNo++;
pcsz++;
}
else if (isdigit(pcsz[0]) && pcsz[1] == '/' && isdigit(pcsz[2]))
{ // Fraction
if (pcsz[3]) // Fraction must be last element in address
return FALSE;
if (pcsz[0] >= pcsz[2]) // Invalid fraction?
return FALSE;
range.cFract = ((pcsz[0] - '0') * 100) / (pcsz[2] - '0');
break;
}
else if (isdigit(pcsz[0]) && pcsz[1] != '/')
{ // Numeric
for (SIZET i = 0; isdigit(pcsz[i]) && pcsz[i+1] != '/'; ++i)
;
if (MAX_RANGE - i)
memset(range.szNo[range.cNo], '0', MAX_RANGE - i);
memcpy(range.szNo[range.cNo] + (MAX_RANGE - i), pcsz, i);
range.szNo[range.cNo][MAX_RANGE] = '\0';
pcsz += i;
range.code = ((range.szNo[range.cNo][MAX_RANGE-1] - '0') % 2) == 0 ? Z4_EVEN: Z4_ODD;
range.cNo++;
}
else if (pcsz[0] == '-' || pcsz[0] == '.')
{ // Dash or period
if (!range.cNo)
return FALSE;
while (pcsz[0] == '-' || pcsz[0] == '.')
pcsz++;
range.afDash[range.cNo - 1] = TRUE;
}
else // Invalid character
return FALSE;
if (!range.cNo) // Invalid range
return FALSE;
return TRUE;
}
//----------------------------------------------------------------------------
// Description:
// Parameters:
// Returns: TRUE if successful.
//----------------------------------------------------------------------------
BOOL FN_M Z4_RANGE::Compare()
{
if (no.cNo != lo.cNo)
return FALSE;
SIZET cHi = 0, cLo = 0;
for (SIZET i = 0; i < no.cNo; ++i)
{
//SHORT sLo = strcmp(no.szNo[i], lo.szNo[i]); org code
//SHORT sHi = strcmp(no.szNo[i], hi.szNo[i]); org code
INT sLo = strcmp(no.szNo[i], lo.szNo[i]);
INT sHi = strcmp(no.szNo[i], hi.szNo[i]);
if (no.afAlpha[i] != lo.afAlpha[i] || sLo < 0 || sHi > 0)
return FALSE;
if (sLo == 0)
cLo++;
if (sHi == 0)
cHi++;
}
if (cHi == hi.cNo && no.cFract > hi.cFract)
return FALSE;
if (cLo == lo.cNo && no.cFract < lo.cFract)
return FALSE;
return TRUE;
}
//----------------------------------------------------------------------------
// Description: Destroy object. Free any resources used by object.
// Normally called by destructor.
// Should allow multiple calls from various classes.
// A class should almost always re-init its variables when
// it is destroyed to prevent accidents.
// Parameters: fDestroyAll Destroy parents also?
// Default is TRUE.
// Returns: TRUE if successful.
//----------------------------------------------------------------------------
BOOL FN_M Z4_RANGE::Destroy(BOOL fDestroyAll)
{
Z4_RANGE::Initialize(CL_INIT_CLASS_VARS);
if (fDestroyAll) // Destroy parent.
Z4_RANGE_PARENT::Destroy(fDestroyAll);
return TRUE;
}
//----------------------------------------------------------------------------
// Description:
// Parameters:
// Returns: TRUE if successful.
//----------------------------------------------------------------------------
BOOL FN_M Z4_RANGE::Exception()
{
return lo.cNo == 1 // Hi/lo range is single numeric
&& !lo.afAlpha[0]
&& no.cNo == 2 // Number is numeric and single alpha
&& !no.afAlpha[0]
&& no.afAlpha[1] // And numeric range is valid
&& strcmp(no.szNo[0], lo.szNo[0]) >= 0
&& strcmp(no.szNo[0], hi.szNo[0]) <= 0
&& no.cFract >= lo.cFract
&& no.cFract <= hi.cFract;
}
//----------------------------------------------------------------------------
// Description: Initialize object.
// Normally called by constructor.
// Should allow multiple calls from various classes.
// Parameters: sInit Initialization code. May be one of the following:
// CL_INIT_CLASS Reset class variables and
// and dynamic allocations for
// this class only.
// CL_INIT_CLASS_VARS Reset class variables for
// this class only.
// CL_INIT_VARS Reset class variables for
// this class only.
// CL_INIT_ALL Initialize class and all
// parent class, including
// dynamic memory allocation.
// Default is CL_INIT_ALL
// Returns: TRUE if successful.
//----------------------------------------------------------------------------
BOOL FN_M Z4_RANGE::Initialize(SHORT sInit)
{
if (sInit == CL_INIT_VARS || sInit == CL_INIT_ALL)
Z4_RANGE_PARENT::Initialize(sInit);
return TRUE;
}
//----------------------------------------------------------------------------
// Description:
// Parameters:
// Returns: TRUE if successful.
//----------------------------------------------------------------------------
BOOL FN_M Z4_RANGE::Input(PSZ pszBuf, PCSZ pcszIn, SIZET cMax)
{
Assert(pcszIn);
for (; pcszIn[0]; ++pcszIn)
{
if (!cMax) // Range is too large
return FALSE;
if (!isspace(*pcszIn)) // Copy and eliminate spaces
*pszBuf++ = *pcszIn;
}
pszBuf[0] = '\0';
return TRUE;
}
//----------------------------------------------------------------------------
// Description:
// Parameters:
// Returns: TRUE if successful.
//----------------------------------------------------------------------------
BOOL FN_M Z4_RANGE::Primary(PCSZ pcszNo, PCSZ pcszLo, PCSZ pcszHi, Z4_CODE code)
{
Assert(pcszNo);
if (pcszLo == NULL || !pcszLo[0]) // No range specified?
return pcszNo[0] == '\0';
if (pcszHi == NULL || !pcszHi[0]) // No high range
pcszHi = pcszLo;
// Clean up input
if (!Input(szNo, pcszNo, MAX_PRI_NO)
|| !Input(szLo, pcszLo, MAX_PRI_NO)
|| !Input(szHi, pcszHi, MAX_PRI_NO))
return FALSE;
if (!Break(szNo, no) // Break into ranges
|| !Break(szLo, lo)
|| !Break(szHi, hi))
return FALSE;
if (strcmp(szNo, szLo) == 0 // Watch for exact match to
|| strcmp(szNo, szHi) == 0) // top or bottom of range
return TRUE;
if (!Validate()) // Validate lo/hi range
return FALSE;
// Check odd/even flag
if (code != Z4_BOTH && no.code != code)
return FALSE;
if (Exception()) // Single alpha exception?
return TRUE;
return Compare();
}
//----------------------------------------------------------------------------
// Description:
// Parameters:
// Returns: TRUE if successful.
//----------------------------------------------------------------------------
BOOL FN_M Z4_RANGE::Secondary(PCSZ pcszNo, PCSZ pcszLo, PCSZ pcszHi, Z4_CODE code)
{
Assert(pcszNo);
if (pcszLo == NULL || !pcszLo[0]) // No range specified?
return pcszNo[0] == '\0';
if (pcszHi == NULL || !pcszHi[0]) // No high range
pcszHi = pcszLo;
// Clean up input
if (!Input(szNo, pcszNo, MAX_SEC_NO)
|| !Input(szLo, pcszLo, MAX_SEC_NO)
|| !Input(szHi, pcszHi, MAX_SEC_NO))
return FALSE;
if (!Break(szNo, no) // Break into ranges
|| !Break(szLo, lo)
|| !Break(szHi, hi))
return FALSE;
if (strcmp(szNo, szLo) == 0 // Watch for exact match to
|| strcmp(szNo, szHi) == 0) // top or bottom of range
return TRUE;
if (!Validate()) // Validate lo/hi range
return FALSE;
// Check odd/even flag
if (code != Z4_BOTH && no.code != code)
return FALSE;
if (Exception()) // Single alpha exception?
return TRUE;
return Compare();
}
//----------------------------------------------------------------------------
// Description:
// Parameters:
// Returns: TRUE if successful.
//----------------------------------------------------------------------------
BOOL FN_M Z4_RANGE::Validate()
{
if (lo.cNo != hi.cNo)
return FALSE;
BOOL fRanged = FALSE;
for (SIZET i = 0; i < lo.cNo; ++i)
{
if (lo.afDash[i] != hi.afDash[i]
|| lo.afAlpha[i] != hi.afAlpha[i])
return FALSE;
//SHORT sResult = strcmp(lo.szNo[i], hi.szNo[i]); org code
INT sResult = strcmp(lo.szNo[i], hi.szNo[i]);
if (sResult > 0) // Invalid range
return FALSE;
if (sResult)
{
if (fRanged) // More than one field ranged
return FALSE;
fRanged = TRUE;
}
}
if (!fRanged) // If ranges are equal, check fractional
if (lo.cFract > hi.cFract)
return FALSE;
return TRUE;
}
//----------------------------------------------------------------------------
//------------------------------- End of File --------------------------------
//----------------------------------------------------------------------------